/*===========================
BA.SLIDER v1.0

*Copyright (C) 2010  Luu Thuc Xuong - BlooApple
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Email: thucxuong@gmail.com - blueflames2007@yahoo.com
URL: http://blooapple.com

Extra Info:
require: jQuery 1.4

Markup:
	<ul id="slider">
		<li class="current"><a href="#"><img src="images/pic1.jpg" alt="pic1" /></a></li>
		<li><a href="#"><img src="images/pic2.jpg" alt="pic2" /></a></li>
		<li><a href="#"><img src="images/pic3.jpg" alt="pic1" /></a></li>
		<li><a href="#"><img src="images/pic4.jpg" alt="pic2" /></a></li>
		<li><a href="#"><img src="images/pic5.jpg" alt="pic1" /></a></li>
		<li><a href="#"><img src="images/pic6.jpg" alt="pic2" /></a></li>
		<li><a href="#"><img src="images/pic7.jpg" alt="pic1" /></a></li>
		<li><a href="#"><img src="images/pic8.jpg" alt="pic1" /></a></li>
		<li><a href="#"><img src="images/pic9.jpg" alt="pic1" /></a></li>
	</ul>

JS:
	$(document).ready(function(){
		$("#slider").baslider({
			"numeric": true,
			"numericId": "numControl",
			"auto":true
		},aO);
	});

	//This options file is included in the packet
	var aO = new Array(){
		....
	}
	
	
CSS: baslider.css is required
	

===========================*/


(function($) {

	$.fn.baslider = function(options,animateObject){
		var defaults = {			
				prevId: 'prev',
				nextId: 'next',
				numeric: false,
				numericId: 'controls',
				auto: false,
				autoDelay: 1000
		}; 
		
		options = $.extend(defaults, options);  
		if(animateObject!==null&&animateObject.length==$(this).find('li').length)	
		{
			this.each(function() {
				
				var sliding=false;
				var sliderWidth = $(this).width();
				var sliderHeight = $(this).height();
				var slider = this;
				var listOfItem = $(this).find("li");
				var sliderLength = listOfItem.length;
				var autoHandler;
				
				function autoSlide(){
					setTimeout(function(){
						sliding = true;
						var currentTag = $(slider).find(".current");
						$(slider).find(".prepare").removeClass('prepare');
						var indexItem = listOfItem.index(currentTag.get(0));
						$(listOfItem.get((indexItem+1)%sliderLength)).addClass('prepare').removeClass('current');
						$(slider).find("li.current").removeClass('staticContent').each(function(){ 
							var currentIndex = listOfItem.index(this);
							if(animateObject[currentIndex]!==undefined)
							{
								BAAnimationIn["BAeffect"+animateObject[currentIndex].type](this,currentIndex,-1);
							}
						});
					},options.autoDelay);
				}
				
				if(options.auto && options.autoDelay)
				{
					autoHandler = setTimeout(autoSlide,options.autoDelay);
				}
				
				
				
				//next and prev and other controls will call this function to define the direction
				function animateDir(dir, BAAnimationIn){
					if(options.auto)
					{	
						clearTimeout(autoHandler);
						options.auto = false;
					}
					else if(!sliding)
					{
						sliding = true;
						var currentTag = $(slider).find(".current");
						$(slider).find(".prepare").removeClass('prepare');
						var indexItem = listOfItem.index(currentTag.get(0));
						
						if(dir<0)
						{	
							//dir: -1 is next, -2 is prev
							if(dir==-1)
							{
								$(listOfItem.get((indexItem+1)%sliderLength)).addClass('prepare').removeClass('current');
							}
							else
							{
								$(listOfItem.get((indexItem-1)%sliderLength)).addClass('prepare').removeClass('current');
							}
						}
						else if(dir>0)
						{
							$(listOfItem.get((dir-1)%sliderLength)).addClass('prepare').removeClass('current');
						}
						
						$(slider).find("li.current").removeClass('staticContent').each(function(){ 
							var currentIndex = listOfItem.index(this);
							if(animateObject[currentIndex]!==undefined)
							{
								BAAnimationIn["BAeffect"+animateObject[currentIndex].type](this,currentIndex,dir);
							}
						});
					}
				}

				function finishSlide(pieceWidth, pieceHeight, dir, duration){

					if(dir<0)
					{
						setTimeout(function(){
							var currentTag = $(slider).find(".current");
							currentTag.find("span span").stop();
							var indexItem = listOfItem.index(currentTag.get(0));
							currentTag.removeClass('current').find("span span").css({
								"left":'0px',
								"opacity":"1",
								"top":"0px",
								"width": pieceWidth+'px',
								"height": pieceHeight+'px'
							});
							
							//alert((indexItem+2)%sliderLength); 
							if(dir==-1){
								$(listOfItem.get((indexItem+1)%sliderLength)).removeClass('prepare').addClass('current staticContent');
								$(listOfItem.get((indexItem+2)%sliderLength)).addClass('prepare').removeClass('current');
							}else if(dir==-2){
								$(listOfItem.get((indexItem-1)%sliderLength)).removeClass('prepare').addClass('current staticContent');
								$(listOfItem.get((indexItem-2)%sliderLength)).addClass('prepare').removeClass('current');
							}
							
							if(options.auto && options.autoDelay && dir==-1)
							{
								autoHandler = setTimeout(autoSlide,options.autoDelay);
							}
							
							sliding =false;
						},duration);
					}
					else if(dir>0){
						setTimeout(function(){
							var currentTag = $(slider).find(".current");
							currentTag.find("span span").stop();
							var indexItem = listOfItem.index(currentTag.get(0));
							currentTag.removeClass('current').find("span span").css({
								"left":'0px',
								"opacity":"1",
								"top":"0px",
								"width": pieceWidth+'px',
								"height": pieceHeight+'px'
							});
							
							//alert((indexItem+2)%sliderLength);
							$(listOfItem.get((dir-1)%sliderLength)).removeClass('prepare').addClass('current staticContent');
							$(listOfItem.get((dir)%sliderLength)).addClass('prepare').removeClass('current');
							sliding =false;
						},duration);
					}
				}

				function deviding(sliderSel){
					$(sliderSel).find("li").each(function(indexNum){
						//is not Full width and height type
						var piecePerRow,row;
						if(animateObject[indexNum].type!=7)
						{
							piecePerRow = animateObject[indexNum].piecePerRow;
							row = animateObject[indexNum].row;
						}
						else
						{
							piecePerRow = row =1;
						}
						var pieceHeight = sliderHeight/row;
						var pieceWidth = sliderWidth/piecePerRow;
						var animateTop = animateObject[indexNum].animateProperties.top;
						var animateLeft = animateObject[indexNum].animateProperties.left;
						if(animateLeft===undefined) 
						{
							animateLeft=0;
						}	
						if(animateTop===undefined)
						{
							animateTop=0;
						}
						animateObject[indexNum].animateProperties.top = animateTop*pieceHeight+'px';
						animateObject[indexNum].animateProperties.left = animateLeft*pieceWidth+'px';
						//var pieceDelay = animateObject[indexNum]["pieceDelay"]
						
						var tempSrc = $(this).find('img').attr('src');
						var container = $(this).find('a');
						
						var temp = $("<span />",{
							'class':'devider'
						});
						
						var childTemp = $("<span />");
						
						childTemp.appendTo(temp);
						
						for(var i=0;i<row*piecePerRow;i++)
						{
							//temp.clone().attr('id','ppp'+i).find('span').css({"left":'0px', "backgroundPosition":"0px -"+(i*136)+"px", "opacity":"1"}).end().appendTo("#aaa");
							temp.clone().css({
								'height': pieceHeight+'px',
								'width': pieceWidth+'px',
								'left': (i%piecePerRow)*pieceWidth+"px",
								'top': Math.floor(i/piecePerRow)*pieceHeight+"px"
							}).children('span').attr('class',i+1).css({
								"left":'0px',
								"top":"0px",
								"backgroundPosition": -(i%piecePerRow)*pieceWidth+"px -"+(Math.floor(i/piecePerRow)*pieceHeight)+"px",
								"opacity":"1",
								"backgroundImage": "url("+tempSrc+")",
								"height":pieceHeight+'px',
								"width":pieceWidth+'px'
							}).end().appendTo(container);
						}
						$(this).find('img').css('display','none');
					});
				}
				
				function randomSort(a,b) {
					return( parseInt( Math.random()*10 ) %2 );
				}
	
				function BAAnimation(){
				
					this.piecePerRow=0;
					this.row=0;
					this.pieceDelay=0;
					this.tempDelay=0;
					this.animateProp={};
					this.pieceWidth=0;
					this.pieceheight=0;
					this.totalPieces = 0;
					this.pieces=new Array();
					
					this.updateArgs = function(listItem,animationTypeIndex,generalType){
						//generalType : the general type of animation includes 3 kind: fully iteral order, partial iteral order, at once (1 piece : this will not be mention in this function)
						this.piecePerRow = animateObject[animationTypeIndex].piecePerRow;
						this.row = animateObject[animationTypeIndex].row;
						this.pieceDuration = animateObject[animationTypeIndex].pieceDuration;
						this.pieceWidth = sliderWidth/this.piecePerRow;
						this.pieceHeight = sliderHeight/this.row;
						this.animateProp = animateObject[animationTypeIndex].animateProperties;
						this.totalPieces = this.row*this.piecePerRow;
						this.pieces = $(listItem).find('span span');
						
						if(generalType==1)
						{
							this.pieceDelay = Math.floor((animateObject[animationTypeIndex].duration-this.pieceDuration)/(this.row+this.piecePerRow-1));
						}
						else if(generalType==2)
						{
							this.pieceDelay = Math.floor((animateObject[animationTypeIndex].duration-this.pieceDuration)/(this.row*this.piecePerRow-1));
						}
					};
				
					this.BAeffect1 = function(listItem,animationTypeIndex, dir){
					
						this.updateArgs(listItem,animationTypeIndex,1);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							tempDelay = ( Math.floor((i)/this.piecePerRow) + i%this.piecePerRow ) * this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
						
					};
					this.BAeffect5 = function(listItem,animationTypeIndex, dir){	
					
						this.updateArgs(listItem,animationTypeIndex,2);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							curRow = Math.floor((i)/this.piecePerRow);
							tempDelay = ( curRow%2 ? (this.piecePerRow*(2*curRow+1)-i) : i+1)*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
						
					};
					this.BAeffect7 = function(listItem,animationTypeIndex, dir){
						pieces = $(listItem).find('span span');

						$(pieces[0]).animate(animateObject[animationTypeIndex].animateProperties,animateObject[animationTypeIndex].duration,function(){
							finishSlide(sliderWidth,sliderHeight,dir);
						});
						
					};
					this.BAeffect3 = function(listItem,animationTypeIndex, dir){

						this.updateArgs(listItem,animationTypeIndex,1);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							var tempDelay = (this.piecePerRow + this.row -( Math.floor((i)/this.piecePerRow) +i%this.piecePerRow))*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
					this.BAeffect6 = function(listItem,animationTypeIndex, dir){
							
						this.updateArgs(listItem,animationTypeIndex,2);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							var curRow = Math.floor((i)/this.piecePerRow);
							var tempDelay = (this.totalPieces - ( curRow%2 ? (this.piecePerRow*(2*curRow+1)-i) : i+1))*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
					this.BAeffect4 = function(listItem,animationTypeIndex, dir){
						
						this.updateArgs(listItem,animationTypeIndex,1);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{						
							var tempDelay = (this.row-Math.floor((i)/this.piecePerRow)+(i)%this.piecePerRow)*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
					this.BAeffect2 = function(listItem,animationTypeIndex, dir){
						this.updateArgs(listItem,animationTypeIndex,1);
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							var tempDelay = (Math.floor((i)/this.piecePerRow)+(this.piecePerRow-(i)%this.piecePerRow))*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
					this.BAeffect8 = function(listItem,animationTypeIndex, dir){
						
						this.updateArgs(listItem,animationTypeIndex,2);
						
						var randArr = new Array();
						for(var j=0;j<this.pieces.length;j++)
						{
							randArr[j] = j+1;
						}
						randArr.sort(randomSort);
						
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							var tempDelay = randArr[i]*this.pieceDelay;
							$(this.pieces[i]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
					this.BAeffect9 = function(listItem,animationTypeIndex, dir){
					
						this.updateArgs(listItem,animationTypeIndex,2);
						
						var tempRow,tempCol,k,tempSwirlArray,addVal; 
						tempRow=this.row; tempCol=this.piecePerRow; k=0; addVal=-1;
						tempSwirlArray = new Array(this.pieces.length+1);
						tempSwirlArray[0] = 0;
						
						while(tempRow && tempCol)
						{
							addVal*=-1;
							for(var i=0;i<tempCol;i++)
							{
								tempSwirlArray[k+1] = tempSwirlArray[k] + addVal;
								k++;
							}
							tempRow--;
							addVal*=this.piecePerRow;
							for(var i=0;i<tempRow;i++)
							{
								tempSwirlArray[k+1] = tempSwirlArray[k] + addVal;
								k++;
							}
							tempCol--;
							addVal/= this.piecePerRow;
						}
						
						finishSlide(this.pieceWidth, this.pieceHeight, dir, animateObject[animationTypeIndex].duration);
						
						for(var i=0;i<this.pieces.length;i++)
						{
							var tempDelay = i*this.pieceDelay;
							$(this.pieces[tempSwirlArray[i+1]-1]).delay(tempDelay).animate(this.animateProp,this.pieceDuration);
						}
					};
				}
			
				
				//Create instance of animation effect object
				deviding(this);
				var BAAnimationIn = new BAAnimation();
				//Keep the normal state of listitem
				$("#slider .current").addClass("staticContent");
				//Define what the next and prev buttons behavior
				$("#"+options.nextId).click(function(){ 
					animateDir(-1, BAAnimationIn);
				});
				$("#"+options.prevId).click(function(){
					animateDir(-2, BAAnimationIn);
				});
				
				if(options.numeric && $("#"+options.numericId).length)
				{
					var tempOrList = $("<ol />");
					for(var i=0;i<sliderLength;i++)
					{	
						$("<li />").html("<a href='#'>"+(i+1)+"</a>").appendTo(tempOrList);
					}
					tempOrList.appendTo("#"+options.numericId);
					$("#"+options.numericId).find("li").each(function(indexNum){
						$(this).click(function(){
							if(listOfItem.index($(slider).find('li.current').get(0)) != indexNum)
							{
								animateDir(indexNum+1,BAAnimationIn);
							}
						});
					});
				}
				
			});
		}
		
		
		
	};
})(jQuery);
